package com.school.sports.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * 裁判分配表实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("referee_assignment")
public class RefereeAssignment {

    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 裁判ID
     */
    @NotNull(message = "裁判ID不能为空")
    private Long refereeId;

    /**
     * 项目ID
     */
    @NotNull(message = "项目ID不能为空")
    private Long projectId;

    /**
     * 轮次
     */
    @Min(value = 1, message = "轮次至少为1")
    private Integer round;

    /**
     * 状态：待确认、已接受、已拒绝
     */
    private String status;

    /**
     * 拒绝原因等反馈
     */
    @Size(max = 200, message = "反馈信息长度不能超过200个字符")
    private String feedback;

    /**
     * 分配时间
     */
    private LocalDateTime assignedAt;

    /**
     * 裁判对象（关联查询时使用）
     */
    @TableField(exist = false)
    private Referee referee;

    /**
     * 项目对象（关联查询时使用）
     */
    @TableField(exist = false)
    private Project project;

    /**
     * 裁判姓名（关联查询时使用）
     */
    @TableField(exist = false)
    private String refereeName;

    /**
     * 裁判等级（关联查询时使用）
     */
    @TableField(exist = false)
    private String refereeLevel;

    /**
     * 项目名称（关联查询时使用）
     */
    @TableField(exist = false)
    private String projectName;

    /**
     * 项目类型（关联查询时使用）
     */
    @TableField(exist = false)
    private String projectType;

    /**
     * 比赛时间（关联自schedule表）
     */
    @TableField(exist = false)
    private LocalDateTime matchTime;

    /**
     * 比赛场地（关联自schedule表）
     */
    @TableField(exist = false)
    private String venueName;

    /**
     * 分配状态枚举
     */
    public enum AssignmentStatus {
        PENDING("待确认"),
        ACCEPTED("已接受"),
        REJECTED("已拒绝");

        private final String displayName;

        AssignmentStatus(String displayName) {
            this.displayName = displayName;
        }

        public String getDisplayName() {
            return displayName;
        }

        /**
         * 根据显示名称获取枚举值
         */
        public static AssignmentStatus fromDisplayName(String displayName) {
            for (AssignmentStatus status : AssignmentStatus.values()) {
                if (status.getDisplayName().equals(displayName)) {
                    return status;
                }
            }
            return null;
        }
    }

    /**
     * 设置分配状态
     */
    public void setStatus(String status) {
        this.status = status;
    }

    /**
     * 获取分配状态显示名称
     */
    public String getStatusDisplayName() {
        AssignmentStatus statusEnum = AssignmentStatus.fromDisplayName(this.status);
        return statusEnum != null ? statusEnum.getDisplayName() : this.status;
    }

    /**
     * 检查是否待确认
     */
    public boolean isPending() {
        return AssignmentStatus.PENDING.getDisplayName().equals(this.status);
    }

    /**
     * 检查是否已接受
     */
    public boolean isAccepted() {
        return AssignmentStatus.ACCEPTED.getDisplayName().equals(this.status);
    }

    /**
     * 检查是否已拒绝
     */
    public boolean isRejected() {
        return AssignmentStatus.REJECTED.getDisplayName().equals(this.status);
    }

    /**
     * 接受分配
     */
    public void acceptAssignment() {
        this.status = AssignmentStatus.ACCEPTED.getDisplayName();
        this.feedback = null;
    }

    /**
     * 拒绝分配
     */
    public void rejectAssignment(String reason) {
        this.status = AssignmentStatus.REJECTED.getDisplayName();
        this.feedback = reason;
    }

    /**
     * 检查是否可以修改状态
     */
    public boolean canModifyStatus() {
        return isPending();
    }

    /**
     * 检查分配是否有效
     */
    public boolean isValid() {
        return refereeId != null && projectId != null && round != null;
    }

    /**
     * 获取分配显示信息
     */
    public String getAssignmentDisplay() {
        StringBuilder display = new StringBuilder();

        if (projectName != null) {
            display.append(projectName);
        }

        if (round != null && round > 1) {
            display.append("(第").append(round).append("轮)");
        }

        if (refereeName != null) {
            display.append(" - ").append(refereeName);
        }

        if (refereeLevel != null) {
            display.append("(").append(refereeLevel).append(")");
        }

        return display.toString();
    }

    /**
     * 获取状态标签样式（用于前端显示）
     */
    public String getStatusTagType() {
        if (isPending()) return "warning";
        if (isAccepted()) return "success";
        if (isRejected()) return "danger";
        return "info";
    }

    /**
     * 获取分配优先级（基于项目时间和裁判等级）
     */
    public Integer getPriority() {
        int priority = 0;

        // 基于裁判等级的优先级
        if (referee != null) {
            priority += referee.getLevelRank() * 100;
        }

        // 基于项目时间的优先级（越近优先级越高）
        if (matchTime != null) {
            long hoursUntilMatch = java.time.Duration.between(
                java.time.LocalDateTime.now(), matchTime).toHours();
            if (hoursUntilMatch >= 0 && hoursUntilMatch <= 24) {
                priority += 50;
            } else if (hoursUntilMatch > 0 && hoursUntilMatch <= 72) {
                priority += 25;
            }
        }

        return priority;
    }

    /**
     * 检查是否为紧急分配
     */
    public boolean isUrgent() {
        if (matchTime == null) return false;

        long hoursUntilMatch = java.time.Duration.between(
            java.time.LocalDateTime.now(), matchTime).toHours();

        return hoursUntilMatch >= 0 && hoursUntilMatch <= 24;
    }

    /**
     * 从关联对象同步字段信息
     */
    public void syncFieldsFromObjects() {
        if (referee != null) {
            this.refereeName = referee.getUser() != null ?
                referee.getUser().getRealName() : null;
            this.refereeLevel = referee.getLevel();
        }

        if (project != null) {
            this.projectName = project.getName();
            this.projectType = project.getType();
        }
    }

    /**
     * 获取所有可能的状态
     */
    public static List<String> getAllStatuses() {
        return Arrays.asList(
            AssignmentStatus.PENDING.getDisplayName(),
            AssignmentStatus.ACCEPTED.getDisplayName(),
            AssignmentStatus.REJECTED.getDisplayName()
        );
    }

    /**
     * 检查分配是否冲突（同一时间同一裁判是否被分配到多个项目）
     */
    public boolean hasConflict(RefereeAssignment other) {
        if (other == null) return false;
        if (!this.refereeId.equals(other.getRefereeId())) return false;
        if (this.matchTime == null || other.getMatchTime() == null) return false;

        // 检查时间是否重叠（这里简化处理，实际应该考虑比赛持续时间）
        return Math.abs(java.time.Duration.between(
            this.matchTime, other.getMatchTime()).toHours()) < 2;
    }

    /**
     * 获取分配统计信息
     */
    public String getStatisticsInfo() {
        StringBuilder info = new StringBuilder();
        info.append("项目：").append(projectName != null ? projectName : "未知");
        info.append("，轮次：").append(round != null ? round : 1);
        info.append("，状态：").append(getStatusDisplayName());

        if (isUrgent()) {
            info.append("（紧急）");
        }

        return info.toString();
    }
}